package com.aaa.system.service.imp;

import com.aaa.entity.RoleUser;
import com.aaa.entity.User;
import com.aaa.system.mapper.RoleMapper;
import com.aaa.system.mapper.UserMapper;
import com.aaa.system.service.UserService;
import com.aaa.system.vo.UserVo;
import com.aaa.utils.TokenUtils;
import com.aaa.utils.WebUtil;
import com.aaa.vo.Result;
import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.PutObjectRequest;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.*;

import static com.aaa.utils.UploadFileUtils.*;
import static com.aaa.utils.UploadFileUtils.BUCKET_NAME;

@Service
public class UserServiceImp implements UserService {

    @Autowired
    private  UserMapper userMapper;

    @Autowired
    private RoleMapper roleMapper;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Bean
    private PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }

    @Override
    public User findByUsername(String username) {
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("phone",username);
        queryWrapper.eq("status",0);
        queryWrapper.eq("del_flag",0);
        return userMapper.selectOne(queryWrapper);
    }

    @Override
    public Result<User> getUserInfo() {
        String token = WebUtil.getRequest().getHeader("token");
        Map<String, Object> map = TokenUtils.getInfo(token);
        //根据手机号进行查询
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("phone",map.get("username"));
        queryWrapper.eq("status",0);
        queryWrapper.eq("del_flag",0);
        User user = userMapper.selectOne(queryWrapper);
        return new Result<>(200,"查询成功",user);
    }

    @Override
    public Result<IPage<User>> findByCondition(UserVo userVo) {
        IPage page = new Page(userVo.getCurrent(),userVo.getSize());
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        if (StringUtils.isNotBlank(userVo.getPhone())){
            queryWrapper.like("phone",userVo.getPhone());
        }
        if (StringUtils.isNotBlank(userVo.getUserName())){
            queryWrapper.eq("user_name",userVo.getUserName());
        }
        if (Objects.nonNull(userVo.getDeptId())){
            queryWrapper.eq("dept_id",userVo.getDeptId());
        }
        if (Objects.nonNull(userVo.getStatus())){
            queryWrapper.eq("status",userVo.getStatus());
        }
        if (Objects.nonNull(userVo.getDateRange())&&userVo.getDateRange().length==2){
            queryWrapper.between("create_time",userVo.getDateRange()[0],userVo.getDateRange()[1]);
        }
        queryWrapper.eq("del_flag",0);
        IPage page1 = userMapper.selectPage(page, queryWrapper);
        return new Result<>(200,"查询用户成功",page1);
    }

    @Override
    public Result<Boolean> saveOrUpd(User user) {
        String token = WebUtil.getRequest().getHeader("token");
        String username = TokenUtils.getInfo(token).get("username").toString();
        //根据手机号进行查询
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("phone",username);
        queryWrapper.eq("status",0);
        queryWrapper.eq("del_flag",0);
        User userdata = userMapper.selectOne(queryWrapper);
        //根据号码查询  是否唯一
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("phone",user.getPhone());
        User user1 = userMapper.selectOne(wrapper);
        //如果用户id存在 则为修改
        if(Objects.nonNull(user.getUserId())){
            user.setDelFlag("0");
            user.setUpdateTime(new Date());
            user.setUpdateBy(userdata.getUserName());
            int i = userMapper.updateById(user);
            return new Result<>(200,"修改用户信息",i>0?true:false);
        }else {
            if(Objects.nonNull(user1)){
                //如果不为空  则用户电话已经被用 返回结果
                return new Result<>(200,"该手机号已经被使用",true);
            }
            //如果用户id不存在 则为添加
            user.setCreateTime(new Date());
            user.setCreateBy(userdata.getUserName());
            user.setDelFlag("0");
            //设置一个固定的密码密码是123
            String password = passwordEncoder().encode("123");
            user.setPassword(password);
            int i = userMapper.insert(user);
            return new Result<>(200,"添加用户成功",i>0?true:false);
        }
    }

    @Override
    public Result<Boolean> delOneUser(Long userId) {
        //该用户分配角色 不能被删除
        List<RoleUser> roleUsers =  roleMapper.selectRoleIdByUserId(userId);
        if (roleUsers.size()>0){
            return new Result<>(200,"该用户已分配角色,不能被删除",true);
        }
        User user = new User();
        user.setUserId(userId);
        user.setDelFlag("1");
        int i = userMapper.updateById(user);
        return new Result<>(200,"成功删除用户信息",i>0?true:false);
    }

    @Override
    public Result<Boolean> bachListUser(Long[] userIds) {
        //该用户分配角色 不能被删除
        List<RoleUser> list =  roleMapper.selectRoleIdByUserIds(userIds);
        if (list.size()>0){
            return new Result<>(200,"该用户已分配角色,不能被删除",true);
        }
        int i = userMapper.bachUser(userIds);
        return new Result<>(200,"批量删除成功",i>0?true:false);
    }

    /**
     * 清空redis
     * @return
     */
    @Override
    public Result<Boolean> clearRedis() {
        HttpServletRequest request = WebUtil.getRequest();
        String token = request.getHeader("token");
        String phone = TokenUtils.getInfo(token).get("username").toString();
        String Addr = request.getRemoteAddr();
        Boolean aBoolean = redisTemplate.delete(token);
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("phone",phone);
        User user = new User();
        user.setLastLoginTime(new Date());
        user.setLastLoginIp(Addr);
        userMapper.update(user,wrapper);
        return new Result<>(200,"清除redis中用户的token",aBoolean);
    }

    @Override
    public Result<Boolean> updUserPassword(String olePass, String pass) {
        String token = WebUtil.getRequest().getHeader("token");
        String phone = TokenUtils.getInfo(token).get("username").toString();

        QueryWrapper wrapper = new QueryWrapper();
        wrapper.eq("phone",phone);
        User user = userMapper.selectOne(wrapper);
        //数据库中用户密码
        String password = user.getPassword();
        System.out.println("password = " + password);
        //输入的旧密码加密比对是否正确
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        boolean matches = passwordEncoder.matches(olePass, password);
        System.out.println("matches = " + matches);
        if (matches){
            //修改密码
            User user1 = new User();
            user1.setUserId(user.getUserId());
            //新密码加密
            String newPassword = passwordEncoder.encode(pass);
            System.out.println("newPassword = " + newPassword);
            user1.setPassword(newPassword);
            int i = userMapper.updateById(user1);
            return new Result<>(200,"密码修改成功",i>0?true:false);
        }
        return new Result<>(200,"旧密码输入错误",false);
    }
    /**
     * 远程调用 查询用户所有的信息
     */
    @Override
    public List<User> getAllUserList() {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("status",0);
        wrapper.eq("del_flag",0);
        List<User> users = userMapper.selectList(wrapper);
        return users;
    }



    /**
     * 远程调用 查询用户是否需要排班
     */
    @Override
    public List<User> queryUserNeedScheduling(Map<String, Object> map) {
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        if (Objects.nonNull(map.get("userId"))){
            userQueryWrapper.eq("user_id",map.get("userId"));
        }
        if (Objects.nonNull(map.get("deptId"))){
            userQueryWrapper.eq("dept_id",map.get("deptId"));
        }
        userQueryWrapper.eq("status",0);
        userQueryWrapper.eq("del_flag",0);
        return userMapper.selectList(userQueryWrapper);
    }

    /**
     * 头像上传
     */
    @Override
    public Result<String> uploadFile(HttpServletRequest request, MultipartFile file) {
        // Endpoint以华东1（杭州）为例，其它Region请按实际情况填写。
        String endpoint = END_POINT;
        // 阿里云账号AccessKey拥有所有API的访问权限，风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维，请登录RAM控制台创建RAM用户。
        String accessKeyId = ACCESS_KEY_ID;
        String accessKeySecret = ACCESS_KEY_SECRET;
        // 填写Bucket名称，例如examplebucket。
        String bucketName = BUCKET_NAME;
        String oldName = file.getOriginalFilename();
        int index = oldName.lastIndexOf(".");
        String suffixName = oldName.substring(index);
        String s = UUID.randomUUID().toString();
        String newName= s + suffixName;
        // 填写Object完整路径，完整路径中不能包含Bucket名称，例如exampledir/exampleobject.txt。
        String objectName = newName;
        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        try {
            // 填写字符串。
            String content = "Hello OSS";
            // 创建PutObjectRequest对象。
            PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objectName,file.getInputStream());
            // 上传字符串。
            ossClient.putObject(putObjectRequest);
        } catch (OSSException oe) {
            System.out.println("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            System.out.println("Error Message:" + oe.getErrorMessage());
            System.out.println("Error Code:" + oe.getErrorCode());
            System.out.println("Request ID:" + oe.getRequestId());
            System.out.println("Host ID:" + oe.getHostId());
        } catch (ClientException ce) {
            System.out.println("Caught an ClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with OSS, "
                    + "such as not being able to access the network.");
            System.out.println("Error Message:" + ce.getMessage());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
        String picpath="https://"+bucketName+"."+endpoint+"/"+objectName;
        return new Result<String>(200,"上传头像成功",picpath);
    }

    /**
     * 远程调用
     * @param userId
     * @return
     */
    @Override
    public String getUsernameById(Long userId) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        if (Objects.nonNull(userId)){
            queryWrapper.eq("user_id",userId);
        }
        User user = userMapper.selectOne(queryWrapper);
        return user.getUserName();
    }
}
